package cn.bitkit.mybatis;

import cn.bitkit.base.exception.BusinessAssert;
import cn.bitkit.base.util.StringUtil;
import cn.bitkit.mybatis.base.BaseMapper;
import cn.bitkit.mybatis.base.BaseSqlBuilder;
import cn.bitkit.mybatis.constants.MapperMethod;
import cn.bitkit.mybatis.entity.EntityClass;
import cn.bitkit.base.util.ReflectUtil;
import cn.bitkit.mybatis.query.QueryCriteria;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.builder.annotation.ProviderContext;

import java.util.Map;

/**
 * sql动态代理
 * @author changbo
 *
 */
@Slf4j
public class SqlProvider {
	
	public String dynamicSql(ProviderContext context, Map<String, Object> map) {
        log.info("[dynamicSql]{}.{}", context.getMapperType().getName(), context.getMapperMethod().getName());
		BusinessAssert.isNotEmpty(map, "[dynamicSql]param can not be null");
		BusinessAssert.isTrue(BaseMapper.class.isAssignableFrom(context.getMapperType()), "[dynamicSql]mapper must be extend "+BaseMapper.class.getName());
		String method = context.getMapperMethod().getName();
		MapperMethod mapperMethod = MapperMethod.get(method);
		BusinessAssert.isNotNull(mapperMethod, "[dynamicSql]method not supported:"+method);
		Class<?> entityClass = ReflectUtil.getActualType(context.getMapperType());
        BaseSqlBuilder builder = mapperMethod.builder;
        boolean linkTable = false;
        if(builder.supportLinkTable()){
            QueryCriteria criteria = (QueryCriteria) map.get("criteria");
            linkTable = StringUtil.hasValue(criteria.getFrom());
        }
        EntityClass entityInfo;
        if(!linkTable){
            entityInfo = EntityInfoHandler.getEntityInfo(entityClass);
        }else {
            entityInfo = new EntityClass();
            entityInfo.setEntity(false);
        }
		String sql = builder.build(entityInfo, map);
		sql = "<script>\n" + sql + "\n</script>";
        log.debug("[dynamicSql]{}", sql);
		return sql;
	}

}
